﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using RG.Common.Export;
using RG.Common.WPF.BaseFrame;
using RG.Common.WPF.Commands;
using RG.Common.WPF.Filters;

namespace RG.Common.WPF.Dialogs
{
    [SupportDataBinding]
    public class FilterSettingsDialogVM : BaseEditableObject<int>, IEditableDialogDataErrorInfo
    {
        public ObservableCollection<FilterSettings> Items { get; set; } 

        // Для настройки колонок в таблицах
        private ObservableCollection<IColumnInfo> SetColumns()
        {
            var col = new ObservableCollection<IColumnInfo>
                          {
                              new ColumnInfoInt<FilterSettings>("№", 50, x => x.Position + 1),
                              new ColumnInfoString<FilterSettings>("Режим", 150, x => x.Mode.ToString())
                                  {TemplateName = "ModeCellTemplate"},
                              new ColumnInfoString<FilterSettings>("Название фильтра", ColumnGridWidthType.Star,
                                                                   x => x.Name),
                          };
            return col;
        }

     
        public IEnumerable<IColumnInfo> Columns { get; set; }

        public FilterSettings SelectedItem { get; set; }

        // изврат, но иначе почему-то CommandParament ругаиЦа и всё громко падает при биндинге UpCmd и DownCmd
        public int MoveZero { get { return 0; } }
        public int MoveOne { get { return 1; } }
        public int MoveTwo { get { return 2; } }

        public ICommand UpCmd { get; set; }
        public ICommand DownCmd { get; set; }

        public List<FilterVisibleMode> Modes { get; set; } 

        public FilterSettingsDialogVM()
        {
            UpCmd = new DelegateCommand<int>(DoUpItem, x => SelectedItem != null);
            DownCmd = new DelegateCommand<int>(DoDownItem, x => SelectedItem != null);
            Modes = Enum.GetValues(typeof (FilterVisibleMode)).ToList<FilterVisibleMode>();

        }

        // двигаем вниз
        private void DoDownItem(int step)
        {
            if (SelectedItem.Position == Items.Count - 1) return;
            if (step == 0) step = Items.Count;
            ChangeItems(SelectedItem.Position, SelectedItem.Position + step);
        }

        // двигаем вверх
        private void DoUpItem(int step)
        {
            if (SelectedItem.Position == 0) return;
            if (step == 0) step = Items.Count;
            ChangeItems(SelectedItem.Position, SelectedItem.Position - step);
        }

        public void Load(IEnumerable<FilterSettings> source)
        {
            Items = source.ToObservableCollection();
            Columns = SetColumns();
        }

        public List<FilterSettings> Get()
        {
            return Items.ToList();
        }
        
        // метод для обмена двух элементов на позициях form и to 
        public void ChangeItems(int from, int to)
        {
            if (from >= Items.Count || from == to || from < 0) return;
            if (to >= Items.Count) to = Items.Count - 1;
            if (to < 0) to = 0;
            var fromItem = Items.FirstOrDefault(x => x.Position == from);
            if (from > to) // двигаем вверх, меняем позиции всех элементов, что выше
                foreach (var itm in Items.Where(x => x.Position < from && x.Position >= to))
                    itm.Position++;
            if (from < to) // двигаем вниз, меняем позиции всех элементов, что ниже
                foreach (var itm in Items.Where(x => x.Position > from && x.Position <= to))
                    itm.Position--;
            // ставим текущий элемент на новое место
            fromItem.Position = to;
            Items = Items.OrderBy(x => x.Position).ToObservableCollection();
            SelectedItem = Items.FirstOrDefault(x => x.Position == to);
            //колдунство
        }

        public string LastError()
        {
            return "";
        }
    }
}
